home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / smailsrc.zip / UUPC.ZIP / LIB.C < prev    next >
Text File  |  1990-04-04  |  7KB  |  350 lines

  1. /*
  2.     For best results in visual layout while viewing this file, set
  3.     tab stops to every 4 columns.
  4. */
  5.  
  6. /*
  7.     lib.c
  8. */
  9.  
  10. #include <stdio.h>
  11. #include <ctype.h>
  12. #include <errno.h>
  13. #include <alloc.h>
  14.  
  15. #include "host.h"
  16. #include "lib.h"
  17.  
  18. static int changedir();
  19.  
  20.  
  21. /*
  22.     MKDIR - like mkdir() but create intermediate directories as well
  23.  
  24.     This routine has dependency on the path separator characters
  25.     being '/', we should relove that somehow someday.
  26. */
  27.  
  28. int MKDIR(path)
  29. char *path;
  30. {
  31.     char *cp = path;
  32.  
  33.     if (*cp == '\0')
  34.         return 0;
  35.  
  36.     /* see if we need to make any intermediate directories */
  37.     while ((cp = strchr(cp, '/')) != nil(char)) {
  38.         *cp = '\0';
  39.         mkdir(path);
  40.         *cp = '/';
  41.         cp++;
  42.     }
  43.  
  44.     /* make last dir */
  45.     return mkdir(path);
  46.  
  47. } /*MKDIR*/
  48.  
  49.  
  50. /*
  51.     CHIDR - like chdir() but create the directory if necessary
  52. */
  53.  
  54. int CHDIR(path)
  55. char *path;
  56. {
  57.  
  58.     if (*path == '\0')
  59.         return 0;
  60.  
  61.     MKDIR(path);
  62.  
  63.     /* change to last directory */
  64.     return changedir(path);
  65.  
  66. } /*CHDIR*/
  67.  
  68.  
  69. /*
  70.     FOPEN - like fopen() but create imtermediate directories
  71.  
  72.     This routine has dependency on the path separator characters
  73.     being '/', we should relove that somehow someday.
  74. */
  75.  
  76. FILE *FOPEN(name, mode, ftype)
  77. char *name, *mode, ftype;
  78. {
  79.  
  80.     char *last;
  81.     FILE *results;
  82.  
  83.     /* are we opening for write or append */
  84.  
  85.     FILEMODE(ftype);
  86.     results = fopen(name, mode);
  87.  
  88.     if ((results != nil(FILE)) || (*mode == 'r'))
  89.         return results;
  90.  
  91.     /* verify all intermediate directories in the path exist */
  92.     if ((last = strrchr(name, '/')) != nil(char)) {
  93.         *last = '\0';
  94.         MKDIR(name);
  95.         *last = '/';
  96.     }
  97.  
  98.     /* now try open again */
  99.     return fopen(name, mode);
  100.  
  101. } /*FOPEN*/
  102.  
  103. int CREAT(name, mode, ftyp)
  104. char *name;
  105. int mode;
  106. char ftyp;
  107. {
  108.  
  109.     char *last;
  110.     int results;
  111.  
  112.     /* are we opening for write or append */
  113.     FILEMODE(ftyp);
  114.     results = creat(name, mode);
  115.  
  116.     if (results != -1)
  117.         return results;
  118.  
  119.     /* see if we need to make any intermediate directories */
  120.     if ((last = strrchr(name, '/')) != nil(char)) {
  121.         *last = '\0';
  122.         MKDIR(name);
  123.         *last = '/';
  124.     }
  125.  
  126.     /* now try open again */
  127.     return creat(name, mode);
  128.  
  129. } /*CREAT*/
  130.  
  131.  
  132. /*
  133.     getargs - return a list of pointers to tokens in the given line
  134. */
  135.  
  136. int getargs(line, flds)
  137. char *line, **flds;
  138. {
  139.     int i = 0;
  140.  
  141.     while ((*line != '\0') && (*line != '\n')) {
  142.         if (isspace(*line))
  143.             line++;
  144.         else {
  145.             *flds++ = line;
  146.             i++;
  147.             while(!isspace(*line) && (*line != '\0'))
  148.                 line++;
  149.             if (isspace(*line))
  150.                 *line++ = '\0';
  151.         }
  152.     }
  153.  
  154.     return i;
  155.  
  156. } /*getargs*/
  157.  
  158.  
  159. static char *S_tzoffset;
  160.  
  161. /* the following table contols the configurations files processing */
  162.  
  163. static struct Table {
  164.     char *sym, **loc, must, sys;
  165. } table[] = {
  166.     "mailbox", &mailbox, TRUE, FALSE,
  167.     "name", &name, TRUE, FALSE,
  168.     "home", &homedir, TRUE, FALSE,
  169.     "maildir", &maildir, TRUE, TRUE,
  170.     "newsdir", &newsdir, TRUE, TRUE,
  171.     "confdir", &confdir, TRUE, TRUE,
  172.     "spooldir", &spooldir, TRUE, TRUE,
  173.     "pubdir", &pubdir, TRUE, TRUE,
  174.     "tempdir", &tempdir, TRUE, TRUE,
  175.     "domain", &domain, TRUE, TRUE,
  176.     "nodename", &nodename, TRUE, TRUE,
  177.     "mailserv", &mailserv, TRUE, TRUE,
  178.     "indevice", &E_indevice, FALSE, TRUE,
  179.     "inspeed", &E_inspeed, FALSE, TRUE,
  180.     "editor", &E_editor, FALSE, FALSE,
  181.     "pager", &E_pager, FALSE, FALSE,
  182.     "tzoffset", &S_tzoffset, TRUE, TRUE,
  183.     "tzname", &E_tzname, FALSE, TRUE,
  184.     "filesent", &E_filesent, FALSE, FALSE,
  185.     "signature", &E_signature, FALSE, FALSE,
  186.     nil(char)
  187. };
  188.  
  189.  
  190. /*
  191.     getconfig - process a configuration file
  192. */
  193.  
  194. static int getconfig(fp, sysmode)
  195. FILE *fp;
  196. int sysmode;
  197. {
  198.     struct Table *tptr;
  199.  
  200.     for ( ; ; ) {
  201.         char buff[80], *cp;
  202.  
  203.         if (fgets(buff, sizeof buff, fp) == nil(char))
  204.             break;        /* end of file    */
  205.  
  206.         if ((*buff == '\n') || (*buff == '#'))
  207.             continue;    /* comment line    */
  208.  
  209.         if (*(cp = buff + strlen(buff) - 1) == '\n')
  210.             *cp = '\0';
  211.         if ((cp = strchr(buff, '=')) == nil(char))
  212.             continue;
  213.         *cp++ = '\0';
  214.         strlwr(buff);
  215.  
  216.         for (tptr = table; tptr->sym != nil(char); tptr++)
  217.             if (equal(buff, tptr->sym)) {
  218.                 if (tptr->sys && !sysmode)
  219.                     printmsg(0,
  220.                         "user specified system parameter \"%s\" ignored.",
  221.                         tptr->sym);
  222.                 else {
  223.                     if (*(tptr->loc) != nil(char))
  224.                         free(*(tptr->loc));    /* free the previous one */
  225.                     *(tptr->loc) = strdup(cp);
  226.                 }
  227.                 break;
  228.             }
  229.  
  230.     } /*for*/
  231.  
  232.     return TRUE;
  233.  
  234. } /*getconfig*/
  235.  
  236.  
  237. /*
  238.    configure - define the global parameters of UUPC
  239. */
  240.  
  241. int configure()
  242. {
  243.     char *sysrc, *usrrc;
  244.     FILE *fp;
  245.     int success, ok;
  246.     struct Table *tptr;
  247.  
  248.     if (!getrcnames(&sysrc, &usrrc))
  249.         return FALSE;
  250.  
  251.     for (tptr = table; tptr->sym != nil(char); tptr++)
  252.         *(tptr->loc) = nil(char);
  253.  
  254.     if ((fp = FOPEN(sysrc, "r", TEXT)) == nil(FILE)) {
  255.         printmsg(0, "cannot open system configuration file \"%s\"", sysrc);
  256.         return FALSE;
  257.     }
  258.     ok = getconfig(fp, TRUE);
  259.     fclose(fp);
  260.     if (!ok)
  261.         return FALSE;
  262.  
  263.     if (usrrc == nil(char))
  264.         return TRUE;
  265.  
  266.     if ((fp = FOPEN(usrrc, "r", TEXT)) == nil(FILE)) {
  267.         printmsg(0, "cannot open user configuration file \"%s\"", usrrc);
  268.         return FALSE;
  269.     }
  270.     ok = getconfig(fp, FALSE);
  271.     fclose(fp);
  272.     if (!ok)
  273.         return FALSE;
  274.  
  275.     success = TRUE;
  276.     for (tptr = table; tptr->sym != nil(char); tptr++) {
  277.         if (tptr->must && (*(tptr->loc) == nil(char))) {
  278.             printmsg(0, "configuration parameter \"%s\" must be set.",
  279.                 tptr->sym);
  280.             success = FALSE;
  281.         }
  282.     }
  283.  
  284.     /* convert time zone offset to internal form */
  285.     {
  286.         register int x;
  287.         x = atoi(S_tzoffset);
  288.         E_tzoffset = (x < 0) ? -1 : 1;
  289.         x = abs(x);
  290.         E_tzoffset *= (x / 100) * 60 + x % 100;
  291.         free(S_tzoffset);
  292.     }
  293.  
  294.     return success;
  295.  
  296. } /*configure*/
  297.  
  298.  
  299. /*
  300.     p r i n t m s g
  301.  
  302.     Print an error message if its severity level is high enough.
  303.     Print message on standard output if not in remote mode (call-in).
  304.     Always log the error message into the log file.
  305. */
  306.  
  307. int debuglevel = 1;
  308. int logecho = FALSE;
  309. FILE *logfile = stdout;
  310.  
  311. /*VARARGS1*/
  312. void printmsg(level, fmt, a1, a2, a3, a4, a5)
  313. int level;
  314. char *fmt;
  315. char *a1, *a2, *a3, *a4, *a5;
  316. {
  317.     char msg[256];
  318.  
  319.     if (level <= debuglevel) {
  320.         sprintf(msg, fmt, a1, a2, a3, a4, a5);
  321.         strcat(msg, "\n");
  322.         if (logecho)
  323.             fputs(msg, stdout);
  324.         fprintf(logfile, "(%d) ", level);
  325.         fputs(msg, logfile);
  326.     }
  327.  
  328. } /*printmsg*/
  329.  
  330.  
  331. /*
  332.     changedir - like chdir() but also changes the current drive
  333. */
  334.  
  335. static int changedir(path)
  336. char *path;
  337. {
  338.  
  339.     if ((*path != '\0') && (path[1] == ':')) {
  340.         unsigned char drive;
  341.         if (((drive = toupper(*path)) >= 'A') && (drive <= 'Z'))
  342.             setdisk(drive - (unsigned char)'A');
  343.         else
  344.             return -1;
  345.     }
  346.  
  347.     return chdir(path);
  348.  
  349. } /*changedir*/
  350.